package com.yiyi.credit.manage.abutment.manage.controller.user;


import com.github.pagehelper.PageInfo;
import com.yiyi.credit.manage.abutment.client.UserAuthorityManagementClient;
import com.yiyi.credit.manage.abutment.common.bean.Response;
import com.yiyi.credit.manage.abutment.common.enums.ResponseCode;
import com.yiyi.credit.manage.abutment.common.exceptions.ServiceException;
import com.yiyi.credit.manage.abutment.common.utils.TokenUtil;
import com.yiyi.credit.manage.abutment.service.UserService;
import com.yiyi.credit.manage.model.entity.CookieInfo;
import com.yiyi.credit.manage.model.po.UserInfoListQueryPo;
import com.yiyi.credit.manage.model.vo.PaginationVo;
import com.yiyi.credit.manage.model.vo.UserInfoVo;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;


@RestController
@RequestMapping("/sseUser")
public class UserAuthorityController {

    private static final Logger logger = LoggerFactory.getLogger(UserAuthorityController.class);

    @Autowired
    UserAuthorityManagementClient userAuthorityManagementClient;
    @Autowired
    UserService userService;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Value("${sysInfoId}")
    private Long sysInfoId;
    @Value("${domainIp}")
    private String domainIp;
    private String regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{6,10}$";


    @ApiOperation(value = "用户登录", notes = "登录权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "用户名", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "authCode", value = "验证码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", paramType = "query")
    })
    @PostMapping("/login")
    public Object login(@RequestParam String userName, @RequestParam String password,
                        @RequestParam String authCode,
                        HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("用户{}正在登录", userName);
        logger.info(request.getRequestURI() + "---" + request.getRemoteHost());

        UserInfoVo userInfoVo;
        Map<String, Object> userMap = new HashMap<>();

        Response<CookieInfo> result = userAuthorityManagementClient.login(userName, password);

        if (!Objects.equals(result.getCode(), "10000")) {
            throw new ServiceException(result.getCode(), result.getMessage());
        }

        String resultToken = result.getResult().getToken();
        userInfoVo = userAuthorityManagementClient.getSysUserInfoByToken(resultToken, sysInfoId).getResult();
        userMap.put("userInfoVo", userInfoVo);
        redisTemplate.opsForValue().set("credit" + resultToken, userMap, 1, TimeUnit.DAYS);

        CookieInfo cookieInfo = result.getResult();

        String token = cookieInfo.getToken();
        Cookie cookie = new Cookie(cookieInfo.getName(), token);
        cookie.setPath("/");
        cookie.setSecure(cookieInfo.isSecure());
        cookie.setMaxAge(cookieInfo.getMaxAge());
        response.addCookie(cookie);
        return new Response<>(userMap);
    }


    @ApiOperation(value = "用户退出", notes = "登录权限")
    @PostMapping("/logout")
    public Object logout(HttpServletRequest request, HttpServletResponse response) {
        logger.info("用户正在登出系统");

        Cookie tokenCookie = TokenUtil.getCookie(request);
        if (tokenCookie != null) {
            Response result = userAuthorityManagementClient.logout(tokenCookie.getValue());
            if (!Objects.equals(result.getCode(), "10000")) {
                return new Response<>(result.getCode(), result.getMessage());
            }

            response.addCookie(logoff(tokenCookie));
            return new Response<>(ResponseCode.SUCCESS);
        }

        return new Response<>(ResponseCode.LOGIN_FIRST);
    }


    @ApiOperation(value = "密码修改", notes = "登录权限")
    @ApiImplicitParams
            ({
                    @ApiImplicitParam(name = "userName", value = "用户名", required = true, dataType = "String", paramType = "query"),
                    @ApiImplicitParam(name = "oldPwd", value = "原密码", required = true, dataType = "String", paramType = "query"),
                    @ApiImplicitParam(name = "newPwd", value = "新密码", required = true, dataType = "String", paramType = "query")
            })
    @PostMapping("/changePwdSysUser")
    public Object changePwdSysUser(@RequestParam(value = "userName") String userName,
                                   @RequestParam(value = "oldPwd") String oldPwd,
                                   @RequestParam(value = "newPwd") String newPwd,
                                   HttpServletRequest request, HttpServletResponse response) {

        if (!newPwd.matches(regexp)) {
            throw new ServiceException("密码强度不够，请确认同时包含大小写字符和数字!");
        }
        Response result = userAuthorityManagementClient.changePwdSysUser(userName, oldPwd, newPwd);

        Cookie tokenCookie = TokenUtil.getCookie(request);
        if (Objects.equals(result.getCode(), "10000")) {
            response.addCookie(logoff(tokenCookie));
            userAuthorityManagementClient.logout(tokenCookie.getValue());
        }
        return new Response<>(result.getCode(), result.getMessage());
    }


    @ApiOperation(value = "用户在当前系统中的权限", notes = "登录权限")
    @ApiImplicitParams
            ({
                    @ApiImplicitParam(name = "userName", value = "用户名", required = true, dataType = "String", paramType = "query")
            })
    @PostMapping("/getSysUserPermission")
    public Object getSysUserPermission(@RequestParam(value = "userName") String userName) {
        Long sysUserId = userAuthorityManagementClient.getSysUserId(userName);
        return userAuthorityManagementClient.getSysUserPermission(sysUserId, sysInfoId);
    }


    @ApiOperation(value = "用户权限", notes = "登录权限")
    @PostMapping("/getSysChildNodePermission")
    public Object getSysChildNodePermission(HttpServletRequest request) {

        String token = (String) request.getAttribute("token");
        if (token == null) {
            return new Response<>(ResponseCode.LOGIN_FIRST);
        }
        Map map = (Map) redisTemplate.opsForValue().get("credit" + token);
        if (map == null) {
            return new Response<>(ResponseCode.NO_USER_INFO);
        }
        UserInfoVo userInfoVo = (UserInfoVo) map.get("userInfoVo");
        if (userInfoVo == null) {
            return new Response<>(ResponseCode.NO_USER_INFO);
        }
        logger.info("用户{}正在获取权限菜单", userInfoVo.getUserName());
        return userAuthorityManagementClient.getSysChildNodePermission(userInfoVo.getId(), sysInfoId, -1L, true);
    }


    @ApiOperation(value = "根据token获取登录用户信息", notes = "用户信息")
    @PostMapping("/getSysUserByToken")
    public Object getSysUserByToken(HttpServletRequest request) {
        String token = (String) request.getAttribute("token");
        if (token == null) {
            return new Response<>(ResponseCode.LOGIN_FIRST);
        }
        return userAuthorityManagementClient.getSysUserInfoByToken(token, sysInfoId);
    }


    @ApiOperation(value = "系统用户信息列表", notes = "系统用户信息列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "realName", value = "姓名", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "roleNameId", value = "角色Id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "状态", dataType = "Long", paramType = "query")
    })
    @PostMapping("/getUserAllInfoList")
    public Response<PageInfo<UserInfoVo>> getUserAllInfoList(@ModelAttribute UserInfoListQueryPo param) {
        PageInfo pageInfo = new PageInfo();
        PaginationVo paginationVo = userAuthorityManagementClient.getUserAllInfoList
                (sysInfoId, param.getUserName(), param.getRealName(), param.getRoleNameId(), param.getStatus(), param.getPageIndex(), param.getPageSize());
        pageInfo.setPageNum(paginationVo.getPageIndex());
        pageInfo.setPageSize(paginationVo.getLength());
        pageInfo.setTotal(paginationVo.getRecordsTotal());
        pageInfo.setPages(paginationVo.getPage());
        pageInfo.setList(paginationVo.getData());
        pageInfo.setSize(paginationVo.getPage());
        pageInfo.setStartRow(paginationVo.getStart() + 1);
        pageInfo.setEndRow(paginationVo.getStart() + paginationVo.getLength());
        return new Response<>(pageInfo);

    }


    @ApiOperation(value = "根据ids获取用户信息", notes = "根据ids获取用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "用户名", dataType = "String", paramType = "query")
    })
    @PostMapping("/getUserInfoByIds")
    public Response<List<UserInfoVo>> getUserInfoByIds(@RequestParam(value = "ids") String ids) {

        List<UserInfoVo> userList = userAuthorityManagementClient.getUserInfoByIds(sysInfoId, ids);
        return new Response<>(userList);
    }


    public Cookie logoff(Cookie tokenCookie) {
        tokenCookie.setMaxAge(0);
        redisTemplate.delete("credit" + tokenCookie.getValue());
        return tokenCookie;
    }


    @ApiOperation(value = "修改手机号", notes = "修改手机号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "用户名", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "newPhone", value = "新手机号", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "authCode", value = "验证码", required = true, dataType = "String", paramType = "query")
    })
    @PostMapping("/updatePhone")
    public Response updatePhone(@RequestParam(value = "userName") String userName,
                                @RequestParam(value = "password") String password,
                                @RequestParam(value = "newPhone") String newPhone,
                                @RequestParam(value = "authCode") String authCode) {
        if (StringUtils.isNotEmpty(authCode)) {

        }
        userAuthorityManagementClient.updatePhone(sysInfoId, userName, password, newPhone);
        return new Response<>(ResponseCode.SUCCESS);
    }


}
